package org.black.phoneUtility.sms.reply.telephony;

import java.util.ArrayList;

import org.black.phoneUtility.sms.reply.app.service.SmsReplyReplyService;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class ReplyPhoneStateListener extends PhoneStateListener {
	private static final String LOG_TAG = ReplyPhoneStateListener.class
			.getName();

	private Context context;
	public static final String PREFERENCE_LAST_MISSED_CALL_TIME = "lastMissedCallTime";
	public static final String PREFERENCE_OLDER_PHONE_STATE = "olderPhoneState";

	private class MissedCallNumberRunnable implements Runnable {
		private Context context;

		public MissedCallNumberRunnable(Context context) {
			this.context = context;
		}

		@Override
		public void run() {
			SharedPreferences sharedPreferences = PreferenceManager
					.getDefaultSharedPreferences(context);
			long currentTimeMillis = System.currentTimeMillis();
			Intent replyMessageServiceIntent = new Intent(context,
					SmsReplyReplyService.class);
			long lastMissedCallTime = sharedPreferences.getLong(
					ReplyPhoneStateListener.PREFERENCE_LAST_MISSED_CALL_TIME,
					Long.MIN_VALUE);
			ArrayList<String> incomingNumbers = new ArrayList<String>();
			if (lastMissedCallTime > Long.MIN_VALUE) {
				try {
					Thread.sleep(4000l);
					Log.i(LOG_TAG,
							"Sleep 4000 milliseconds in order to wait missed call data have been written to db.");
				} catch (Exception e) {
					Log.e(LOG_TAG, "Sleep 4000 milliseconds fail!", e);
				}
				Cursor missedCallCursor = null;
				try {
					missedCallCursor = this.context.getContentResolver()
							.query(CallLog.Calls.CONTENT_URI,
									new String[] { CallLog.Calls.NUMBER },
									CallLog.Calls.TYPE + " = "
											+ CallLog.Calls.MISSED_TYPE
											+ " AND " + CallLog.Calls.DATE
											+ " >= ? ",
									new String[] { String
											.valueOf(lastMissedCallTime) },
									CallLog.Calls.DATE + " DESC");
					sharedPreferences
							.edit()
							.putLong(
									ReplyPhoneStateListener.PREFERENCE_LAST_MISSED_CALL_TIME,
									System.currentTimeMillis()).commit();
					if (missedCallCursor.moveToFirst() == true) {
						do {
							String number = missedCallCursor
									.getString(missedCallCursor
											.getColumnIndex(CallLog.Calls.NUMBER));
							if (number != null) {
								incomingNumbers.add(number.trim());
							}
						} while (missedCallCursor.moveToNext() == true);
					}
				} catch (Throwable throwable) {
					Log.e(LOG_TAG, "Unknown Error!", throwable);
				} finally {
					if (missedCallCursor != null) {
						try {
							missedCallCursor.close();
						} catch (Throwable th) {
							Log.e(LOG_TAG, "Unable to close incoming cursor!",
									th);
						}
					}
				}
			}

			Bundle arguments = new Bundle();
			arguments.putStringArrayList(
					SmsReplyReplyService.ARGUMENTS_NUMBERS, incomingNumbers);
			arguments.putInt(SmsReplyReplyService.ARGUMENTS_NUMBERS_TYPE,
					SmsReplyReplyService.NUMBERS_TYPE_PHONE);
			arguments
					.putLong(
							SmsReplyReplyService.ARGUMENTS_CURRENT_DATE_TIME_IN_MILLISECONDS,
							currentTimeMillis);
			replyMessageServiceIntent.putExtras(arguments);
			context.startService(replyMessageServiceIntent);
		}

	}

	public ReplyPhoneStateListener(Context context) {
		this.context = context;
	}

	@Override
	public void onCallStateChanged(int state, String incomingNumber) {
		SharedPreferences sharedPreferences = PreferenceManager
				.getDefaultSharedPreferences(context);

		int olderSharedPreference = sharedPreferences.getInt(
				ReplyPhoneStateListener.PREFERENCE_OLDER_PHONE_STATE, -1);
		Log.d(LOG_TAG, "Old phone state: " + olderSharedPreference);

		SharedPreferences.Editor editor = sharedPreferences.edit();
		editor.putInt(ReplyPhoneStateListener.PREFERENCE_OLDER_PHONE_STATE,
				state);
		editor.commit();
		Log.d(LOG_TAG, "Write phone state: " + state);

		switch (state) {
		case TelephonyManager.CALL_STATE_IDLE:
			if (olderSharedPreference == TelephonyManager.CALL_STATE_OFFHOOK
					|| olderSharedPreference == TelephonyManager.CALL_STATE_RINGING) {
				new Thread(new MissedCallNumberRunnable(context)).start();
			}
			break;
		case TelephonyManager.CALL_STATE_OFFHOOK:
			break;
		case TelephonyManager.CALL_STATE_RINGING:
			break;
		}
	}
}
